﻿using Microsoft.AspNetCore.Mvc;
using System.Net;
using System.Runtime.Intrinsics.Arm;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Extensions.Options;
using ShopeeWebApi.Model;
using System.Net.Http;
using System;
using ShopeeV2.IBll;
using ShopeeV2.Bll;
using ShopeeV2.Models;
using System.Linq;
using System.Collections.Generic;
using ShopeeWebApi.Model.Enum;
using Attribute = ShopeeWebApi.Model.Attribute;
using Newtonsoft.Json;
using System.Diagnostics;
using Microsoft.Extensions.Logging;

namespace ShopeeWebApi.Controllers;

[ApiController]
[Route("[controller]")]
public class ShopeeController : ControllerBase
{
    private ProductNodeDBContext DBContext;
    private IAuth authMethod = new Auth();
    private IProduct productMethod = new Product();
    private IShop shopMethod = new Shop();
    private IPublic publicMethod = new Public();
    private DBExcute dbExcute = new DBExcute();
    private readonly ILogger<ShopeeController> logger;

     static ShopeeOption shopeeOption = new ShopeeOption()
    {
        PartnerId = 1004247,
    };

    public ShopeeController(ProductNodeDBContext _DBContext, ILogger<ShopeeController> _logger)
    {
        DBContext = _DBContext;
        logger = _logger;
    }

    /// <summary>
    /// 认证
    /// </summary>
    [HttpGet]
    [Route("/Shopee/GetGrantAuthorization")]
    public IActionResult GetGrantAuthorization()
    {
        string path = "/api/v2/shop/auth_partner";
        string url = authMethod.GetAuthURL(path);
        return new JsonResult("{'result':200,'msg':'" + url + "'}");
    }

    /// <summary>
    /// 授权 post
    /// </summary>
    [HttpPost]
    [Route("/Shopee/GetAccessToken")]
    public IActionResult GetAccesstoken([FromBody] TokenParams p)
    {
        if (p is not null && p.ShopId != 0 && !string.IsNullOrWhiteSpace(p.Code))
        {
            RequestAccessToken requestAccessToken = new RequestAccessToken()
            {
                Code = p.Code,
                PartnerId = shopeeOption.PartnerId,
                CommonParamType = EShopeeCommonParamType.COMMON,
                ShopId = p.ShopId,
                MainAccountID=0
            };
            //调用方法
            var result = authMethod.GetAccessToken(requestAccessToken).Result;
            if (string.IsNullOrWhiteSpace(result.Error))
            {
                UserInfo userInfo = new UserInfo()
                {
                    ShopId = p.ShopId,
                    AccessToken = result.AccessToken,
                    ExpireIn = result.ExpireIn,
                    RefreshAccessToken = result.RefreshToken,
                    ShopIdList = result.ShopIdList is null ? "" : result.ShopIdList.ToString(),
                    MainAccountIdList = result.MerchantIdList is null ? "" : result.MerchantIdList.ToString(),
                    GetTime = DateTime.Now
                };
                var shopInfo = DBContext.UserInfo.Where(x => x.ShopId == userInfo.ShopId).FirstOrDefault();
                if (shopInfo is null)
                {
                    DBContext.UserInfo.Add(userInfo);
                }
                else
                {
                    DBContext.UserInfo.Update(userInfo);
                }
                DBContext.SaveChangesAsync();
                return new JsonResult("{'result':1,'msg':'授权成功'}");
            }
            else
            {
                return new JsonResult("{'result':-1,'msg':'" + result.Error + "'}");
            }
        }
        else
        {
            return new JsonResult("{'result':-1,'msg':'参数传递失败！'}");
        }
    }


    [HttpGet]
    [Route("/Shopee/RefreshAccessToken")]
    public async void RefreshAccessToken(string refreshToken, int shopid)
    {
        RequestRefreshAccessToken request = new RequestRefreshAccessToken()
        {
            ShopId = shopid,
            RefreshToken = refreshToken,
        };
        //调用方法
        var result = authMethod.RefreshAccessToken(request);
    }


    [HttpGet]
    [Route("/Shopee/GetShopIDs")]
    public IEnumerable<AreaShopInfo> GetShopIDs()
    {
        Stopwatch stopwatch = new Stopwatch();
        //stopwatch.Start();
        ////左连接 groupjoin实现方式
        //var joinResults = shopeeDBContext.Area.GroupJoin(
        //                  shopeeDBContext.AreaCategoryRelation.GroupBy(g => g.AreaId)
        //                    .Select(g => new { num = g.Count(), AreaId = g.Key }),
        //                    p => p.AreaId, d => d.AreaId,
        //                  (p, g) => new
        //                  {
        //                      AreaId = p.AreaId,
        //                      AreaName = p.AreaName,
        //                      ShorterForm = p.ShorterForm,
        //                      ShopId = p.ShopId,
        //                      h = g
        //                  })
        //                  .SelectMany(c => c.h.DefaultIfEmpty(),
        //                  (a, b) => new AreaShopInfo
        //                  {
        //                      AreaId = a.AreaId,
        //                      AreaName = a.AreaName,
        //                      ShopId = a.ShopId,
        //                      IsExist = b.num > 0 ? true : false,
        //                      ShorterForm = a.ShorterForm
        //                  }).ToList();
        //stopwatch.Stop();
        //string time = stopwatch.ElapsedMilliseconds.ToString();//959,946...975
        //return joinResults;

        stopwatch.Start();
        var x = DBContext.Area.Where(w => w.Platform == EnumPlatform.Shopee).Select(x => new AreaShopInfo
        {
            Id = x.Id,
            AreaName = x.AreaName,
            ShopId = x.ShopId,
            ShorterForm = x.ShorterForm,
            IsExist = x.AreaCategoryRelations.Count() > 0 ? true : false,
            Count = x.AreaCategoryRelations.Count(x => x.HasChildren == false && x.Flag == false),
            ShopType = x.ShopType == null ? "" : getShopType(x.ShopType),
        }).ToList();
        stopwatch.Stop();
        string time2 = stopwatch.ElapsedMilliseconds.ToString();//962,954      
        return x;
    }

    public static string getShopType(EnumShopType? i)
    {
        string shoptype = "";
        switch(i)
        {
            case EnumShopType.LocalShop:
                shoptype = "LocalShop";
                break;
            case EnumShopType.CrossBorderShop:
                shoptype = "CrossBorderShop";
                break;
            case EnumShopType.Merchant:
                shoptype = "Merchant";
                break;
            default:
                break;
        }
        return shoptype;
    }


     void DeleteDatasByCategoryId(int areaId)
    {
        var relations = DBContext.AreaCategoryRelation.Where(e => e.AId == areaId && e.Platform==EnumPlatform.Shopee).ToList();
        if (relations is not null && relations.Count() > 0)
        {
            foreach (var r in relations)
            {
                DBContext.Remove(r);
            }
            DBContext.SaveChanges();
        }
    }


    /// <summary>
    /// 获取分类-add category
    /// </summary>
    /// <param name="areaId"></param>
    /// <param name="shopId"></param>
    /// <returns></returns>
    [HttpGet]
    [Route("/Shopee/GetCategory")]
    public IActionResult GetCategory(int areaId, int shopId)
    {
        if (areaId != 0 && shopId != 0)
        {
            //删除旧的地区和分类目录关系
            DeleteDatasByCategoryId(areaId);
            RequestGetCategory request = new RequestGetCategory()
            {
                ShopId = shopId                                                                                                             
            };
            var categoryResult = productMethod.GetCatagory(request).Result;
            if (categoryResult.IsSuccess)
            {
                var categoryList = categoryResult.Result;              
                if (categoryList is not null)
                {
                    List<AreaCategoryRelation> AreaCategoryRelationList = new List<AreaCategoryRelation>();                                      
                    foreach (var category in categoryList.CategoryList)
                    {                       
                        Category newCategory = new Category(category.OriginalCategoryName, category.DisplayCategoryName, 
                            EnumPlatform.Shopee,category.CategoryId,category.ParentCategoryId);
                        //根据OriginalNname和DisplayName比较是否存在
                        var dbCategory = DBContext.Category.Where(x => x.OriginalName == category.OriginalCategoryName && x.DisplayName==category.DisplayCategoryName
                        && x.Platform == EnumPlatform.Shopee).FirstOrDefault();

                        AreaCategoryRelation ACategoryRelation = new AreaCategoryRelation(areaId, 
                            dbCategory is null ? newCategory : dbCategory,
                            category.CategoryId, category.ParentCategoryId,
                            EnumStatus.ADD, 0, category.HasChildren, EnumPlatform.Shopee);
                        AreaCategoryRelationList.Add(ACategoryRelation);
                    }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
                    DBContext.AreaCategoryRelation.AddRange(AreaCategoryRelationList);
                    DBContext.SaveChanges();
                    return new JsonResult("{'result':1,'msg':'获取分类目录成功！'}");
                }
                else
                {
                    return new JsonResult("{'result':1,'msg':'该目录分类下没有属性'}");
                }
            }
            else
            {
                return new JsonResult("{'result':-2,'msg':'" + categoryResult.Message + "'}");
            }
        }
        else
        {
            return new JsonResult("{'result':-1,'msg':'参数传递失败！'}");
        }
    }

  
    /// <summary>
    /// 获取shopee下所有categoryIdList的叶子节点 
    /// </summary>
    /// <param name="areaId"></param>
    /// <param name="shopId"></param>
    /// <returns></returns>
    [HttpGet]
    [Route("/Shopee/GetCategoryLeafNode")]
    public IEnumerable<long?> GetCategoryLeafNode(int areaId)
    {
        List<AreaCategoryRelation> AreaCategoryRelations = new List<AreaCategoryRelation>();
        //更新category表的目录解析标志
        var categoryModels = DBContext.AreaCategoryRelation.Where(x => x.AId == areaId).ToList();
        foreach(var categoryModel in categoryModels)
        {
            categoryModel.ChangeFlag = false;
            AreaCategoryRelations.Add(categoryModel);
        }
        DBContext.AreaCategoryRelation.UpdateRange(AreaCategoryRelations);
        DBContext.SaveChanges();
        var categoryIds = DBContext.AreaCategoryRelation.Where(a => a.AId == areaId && a.Platform == EnumPlatform.Shopee
                        && a.Status == EnumStatus.ADD && a.HasChildren == false).Select(s => s.CategoryId);
        return categoryIds;
    }


    /// <summary>
    /// 获取shopee下所有categoryIdList的叶子节点 
    /// </summary>
    /// <param name="areaId"></param>
    /// <param name="shopId"></param>
    /// <returns></returns>
    [HttpGet]
    [Route("/Shopee/GetCIDByAid")]
    public IEnumerable<long> GetCIDByAid(int areaId)
    {             
        var categoryIds = DBContext.AreaCategoryRelation.Where(a => a.AId == areaId && a.Platform == EnumPlatform.Shopee
                        && a.Status == EnumStatus.ADD && a.HasChildren == false).Select(s => s.CId);
        return categoryIds;
    }





    /// <summary>
    /// 获取shopee下某个地方的所有categoryIdList的节点 
    /// </summary>
    /// <param name="areaId"></param>  
    /// <returns></returns>
    [HttpGet]
    [Route("/Shopee/GetCategorByAreaID")]
    public IEnumerable<long?> GetCategorByAreaID(int areaId)
    {
        var categoryIds = DBContext.AreaCategoryRelation.Where(a => a.AId == areaId && a.Platform == EnumPlatform.Shopee 
        && a.Status == EnumStatus.ADD).Select(s => s.CategoryId);
        return categoryIds;
    }


    /// <summary>
    /// shopee-指定地区下所有叶子节点，分页展示
    /// </summary>
    /// <param name="areaId"></param>
    /// <param name="currentPage"></param>
    /// <param name="pagesize"></param>
    /// <returns></returns>
    [HttpGet]
    [Route("/Shopee/GetCategoryList")]
    public pagingModel<CategoryItem> GetCategoryList(int areaId, int currentPage = 0, int pagesize = 10)
    {      
        int totalCounts = DBContext.AreaCategoryRelation.Where(a => a.AId == areaId && a.Platform == EnumPlatform.Shopee 
                                                            && a.Status == EnumStatus.ADD && a.HasChildren == false).Count();
        var items = DBContext.AreaCategoryRelation.Where(a => a.AId == areaId && a.Platform == EnumPlatform.Shopee 
                                                                && a.Status == EnumStatus.ADD &&a.HasChildren == false)
           .Select(s => new CategoryItem
           {
               CategoryId = s.CategoryId,
               OriginalNname = s.Category.OriginalName,
               CategoryParentId = s.CategoryParentId,              
               Flag =s.Flag,
               ChangeFlag=s.ChangeFlag,
           }).OrderByDescending(o => o.Flag == false).Skip(pagesize * (currentPage - 1)).Take(pagesize).Select(s => s);
       
        pagingModel<CategoryItem> myPageModel = new pagingModel<CategoryItem>()
        {
            PageSize = pagesize,
            CurrentPage = currentPage,
            TotalCount = totalCounts,
            PageCount = totalCounts % pagesize > 0 ? totalCounts / pagesize + 1 : totalCounts / pagesize,
            Lists = items.AsQueryable()
        };
        return myPageModel;
    }


    [HttpGet]
    [Route("/Shopee/GetAttributeValue")]
    public IActionResult GetAttributeValue(int areaId, int shopId, long categroyID)
    {
        if (shopId != 0 && areaId != 0 && categroyID != 0)
        {          
            var categoryModel = DBContext.AreaCategoryRelation.Where(x => x.AId == areaId && x.CategoryId == categroyID
                                  && x.Platform == EnumPlatform.Shopee && x.Status == EnumStatus.ADD).FirstOrDefault();
            if (categoryModel is not null)
            {
                RequestGetAttributes requestGetAttributes = new RequestGetAttributes()
                {
                    CategoryId = categoryModel.CategoryId,
                    ShopId = shopId
                };
                var resultAttr = productMethod.GetAttributes(requestGetAttributes).Result;
                if (!resultAttr.IsSuccess)
                {
                    return new JsonResult("{'result':-1,'msg':'查询出错了，[" + resultAttr.Message + "];'}");
                }
                var attributes = resultAttr.Result;
                List<CategoryAttrRelation> categoryAttrRelations = new List<CategoryAttrRelation>();

                if (attributes is not null && attributes.AttributeList is not null)
                {
                    List<AttrValueRelation> attrValueRelations = new List<AttrValueRelation>();
                    foreach (var attr in attributes.AttributeList)
                    {                       
                            ////save attribute && value                       
                            var attribute = DBContext.Attribute.Where(x => x.AttributeId == attr.AttributeId
                                                        && x.Platform == EnumPlatform.Shopee).FirstOrDefault();

                        Attribute attrModel = new Attribute(attr.OriginalAttributeName, attr.DisplayAttributeName,
                            DBExcute.getInputType(attr.InputValidationType),
                            DBExcute.getFormatType(attr.FormatType), DBExcute.getDateFormatType(attr.DateFormatType),
                            DBExcute.getType(attr.InputType), DBExcute.getStringByArray(attr.AttributeUnit),
                            DBExcute.getStringByArray(attr.AttributeValueList), null, null, EnumPlatform.Shopee, null, null, null,attr.AttributeId);

                        var a = attribute == null ? attrModel : attribute;
                        var categoryAttrRelation = new CategoryAttrRelation(categoryModel.CId, a, attr.AttributeId, EnumPlatform.Shopee,
                                                                            DBExcute.getIsMandatory(attr.IsMandatory), 0, null, null, null);
                        categoryAttrRelations.Add(categoryAttrRelation);
                       
                        if (attr.AttributeValueList.Count() > 0)
                        {                          
                            foreach (var v in attr.AttributeValueList)
                            {                               
                                var temp = DBContext.Value.Where((x) =>x.ValueId==v.ValueId && x.Platform == EnumPlatform.Shopee).OrderByDescending(x=>x.ValueId).FirstOrDefault();
                                if(temp is null)
                                {
                                    var valueModel = new Value(v.OriginalValueName, v.DisplayValueName, EnumPlatform.Shopee, v.ValueId);
                                    var valueRelation = new AttrValueRelation(a, valueModel, v.ValueId, EnumPlatform.Shopee, categoryModel.CId);
                                    attrValueRelations.Add(valueRelation);
                                }
                                else
                                {
                                    var relationTemp = DBContext.AttrValueRelation.Where(x => x.VId == temp.Id &&x.AttrId==a.Id
                                    && x.Platform == EnumPlatform.Shopee && x.CId== categoryModel.CId).OrderByDescending(x => x.Id).FirstOrDefault(); ;
                                    if(relationTemp is null)
                                    {
                                        var valueRelation = new AttrValueRelation(a, temp, v.ValueId, EnumPlatform.Shopee, categoryModel.CId);
                                        attrValueRelations.Add(valueRelation);
                                    }
                                }                                                            
                            }                           
                        }
                    }                   
                    DBContext.CategoryAttrRelation.AddRange(categoryAttrRelations);
                    DBContext.AttrValueRelation.AddRange(attrValueRelations);                   
                    //更新category表的目录解析标志和属性json值           
                    categoryModel.Flag = true;
                    DBContext.AreaCategoryRelation.Update(categoryModel);
                    DBContext.SaveChanges();
                    return new JsonResult("{'result':1,'msg':'categroyID:" + categroyID.ToString() + "下属性值保存成功！'}");
                }
                else
                {
                    string message = $"{categroyID.ToString()}分类下没有属性!";
                    ErrorDatas errorDatas = new ErrorDatas(EnumPlatform.Shopee, null, null, message);
                    DBContext.ErrorDatas.Add(errorDatas);
                    //更新category表的目录解析标志和属性json值           
                    categoryModel.Flag = true;
                    DBContext.AreaCategoryRelation.Update(categoryModel);
                    DBContext.SaveChanges();
                    return new JsonResult("{'result':1,'msg':'该分类下没有属性！categoryId:[" + categroyID.ToString() + "];'}");
                }
            }
            else
            {
                return new JsonResult("{'result':-1,'msg':'没有找到该分类目录ID！categoryId:[" + categroyID.ToString() + "];'}");
            }
        }
        else
        {
            return new JsonResult("{'result':-1,'msg':'参数传递失败！'}");
        }
    }


    /// <summary>
    ///获取归档数据   
    /// </summary>
    /// <param name="cid"></param>
    [HttpGet]
    [Route("/Shopee/GetDatas")]
    public IActionResult GetDatas(long cid)
    {       
        List<CategoryAttrRelation> relations = new List<CategoryAttrRelation>();
        var categoryModel = DBContext.AreaCategoryRelation.Where(x => x.CId == cid).FirstOrDefault();
        if (categoryModel is not null)
        {
            var attributeLists = DBContext.CategoryAttrRelation.Where(x => x.CId == cid
                  && x.Platform == EnumPlatform.Shopee && x.Status == EnumStatus.ADD
                ).ToList();
            foreach (var attr in attributeLists)
            {
                var attrLists = DBContext.AttrValueRelation.Where(x => x.AttrId == attr.AttrId && x.Status == EnumStatus.ADD
                  && x.Platform == EnumPlatform.Shopee && x.CId == cid).Select(c => new
                  {
                      vid = c.VId,
                      attrid = c.AttrId,
                      cid = c.CId,
                      valueId = c.ValueId,
                      OriginalName = c.Value.OriginalName,
                      DisplayName = c.Value.DisplayName,
                  }).ToList();
                attr.Values = DBExcute.getStringByArray(attrLists);
                relations.Add(attr);              
            }

            var dataLists = DBContext.CategoryAttrRelation.Where(x => x.CId == cid
            && x.Platform == EnumPlatform.Shopee && x.Status == EnumStatus.ADD
            ).Select(s => new
            {
                id = s.AttrId,
                OriginalName = s.attribute.OriginalName,
                DisplayName = s.attribute.DisplayName,
                InputType = s.attribute.InputType,
                FormatType = s.attribute.FormatType,
                DateFormatType = s.attribute.DateFormatType,
                Type = s.attribute.Type,
                AttributeUnit = s.attribute.AttributeUnit,
                IsMandatory = s.IsMandatory,
                Datas = s.attribute.AttrValueRelations.Where(s => s.CId == cid).Select(c => new
                {
                    vid = c.VId,
                    attrid = c.AttrId,
                    cid = c.CId,
                    valueId = c.ValueId,
                    OriginalName = c.Value.OriginalName,
                    DisplayName = c.Value.DisplayName,
                }),
            }).ToList();
            categoryModel.Datas = DBExcute.getStringByArray(attributeLists);
            DBContext.AreaCategoryRelation.Update(categoryModel);
            DBContext.CategoryAttrRelation.AddRange(relations);
        }
        DBContext.SaveChanges();
        return new JsonResult("{'result':1,'msg':'获取归档数据成功！'}");       
    }
    

    /// <summary>
    /// shopee的删除思路：value，attribute，category是共用的一套，
    /// 且同一分类下的属性和值是一致的，所以只新增，更新，但不删除，
    /// 只删除AreaCategoryRelation关系表
    /// </summary>
    /// <param name="areaId"></param>
    /// <param name="shopId"></param>
    /// <returns></returns>
    [HttpGet]
    [Route("/Shopee/ClearData")]
    public IActionResult ClearData(int areaId)
    {
        if (areaId != 0)
        {               
            var areaCategoryList = DBContext.AreaCategoryRelation.Where(x => x.AId == areaId).ToList();
            DBContext.AreaCategoryRelation.RemoveRange(areaCategoryList);
            DBContext.SaveChanges();
            return new JsonResult("{'result':1,'msg':'数据清空成功！'}");
        }
        else
        {      
            return new JsonResult("{'result':-1,'msg':'数据清空失败！'}");
        }
    }

    [HttpGet]
    [Route("/Shopee/UpdateCategory")]
    public IActionResult UpdateCategory(int areaId, int shopId)
    {
        if (areaId != 0 && shopId != 0)
        {
            RequestGetCategory request = new RequestGetCategory()
            {
                ShopId = shopId
            };
            var categoryResult = productMethod.GetCatagory(request).Result;
            if (categoryResult.IsSuccess)
            {
                var categoryList = categoryResult.Result;
                //该地区下所有分类
                if (categoryList is not null && categoryList.CategoryList.Count() > 0)
                {
                    //该地区下所有在用的分类
                    var DBCategoryList = DBContext.AreaCategoryRelation.Where(a => a.AId == areaId 
                    && a.Platform == EnumPlatform.Shopee && a.Status == EnumStatus.ADD).Select(x => new
                    {
                        CID = x.CId,
                        CategoryId = x.CategoryId,
                        CategoryParentId = x.CategoryParentId,
                        OriginalName = x.Category.OriginalName,
                        DisplayName = x.Category.DisplayName,
                        HasChildren = x.HasChildren,
                    }).ToList();
                  
                    if (DBCategoryList is not null && DBCategoryList.Count() > 0)
                    {
                        #region 判断有没有新增：add category,add RC
                        List<AreaCategoryRelation> areaCategoryRelations = new List<AreaCategoryRelation>();

                        var addCategoryIDList = categoryList.CategoryList.Select(x => x.CategoryId)
                            .Except(DBCategoryList.Select(d => d.CategoryId));
                        if (addCategoryIDList is not null)
                        {
                            foreach (var a in addCategoryIDList)
                            {

                                var category = categoryList.CategoryList.Where(x => x.CategoryId == a)
                                    .FirstOrDefault();
                                if (category is not null)
                                {                                   
                                    Category newCategory = new Category(category.OriginalCategoryName, 
                                        category.DisplayCategoryName,
                                         EnumPlatform.Shopee,category.CategoryId,category.ParentCategoryId);

                                    var dbCategory = DBContext.Category.Where(x => x.CategoryId == category.CategoryId
                                    && x.Platform == EnumPlatform.Shopee).FirstOrDefault();
                                    AreaCategoryRelation ACategoryRelation = new AreaCategoryRelation(areaId, 
                                        dbCategory is null ? newCategory : dbCategory,
                                        category.CategoryId, category.ParentCategoryId, 
                                        EnumStatus.ADD, 0, category.HasChildren, EnumPlatform.Shopee);

                                    areaCategoryRelations.Add(ACategoryRelation);
                                }
                                else
                                {
                                    return new JsonResult("{'result':-1,'msg':'[" + a.ToString() + "]目录不在接口数据中，请确认！}");
                                }
                            }
                            DBContext.AreaCategoryRelation.AddRange(areaCategoryRelations);
                        }
                        #endregion

                        #region 判断有没有删除: update RA del;update RC del;update RV del
                        var delCategorys = DBCategoryList.Select(x => x.CategoryId).Except(categoryList.CategoryList.Select(x => x.CategoryId));
                        if (delCategorys is not null && delCategorys.Count() > 0)
                        {
                            foreach (var delCategory in delCategorys)
                            {
                                var category = DBCategoryList.Where(x => x.CategoryId == delCategory).FirstOrDefault();
                                if (category is not null)
                                {
                                    delAreaCategoryRelation(category.CID);
                                    delCategoryAttrRelation(category.CID);
                                }
                                else
                                {
                                    return new JsonResult("{'result':-1,'msg':'[" + delCategory.ToString() + "]目录不在数据库数据中，请确认！}");
                                }
                            }
                        }
                        #endregion

                        #region 取两个数据源的交集：判断有没有修改:add category;add newRC;update RC;update RA;

                        var updateCategoryIDList = categoryList.CategoryList.Select(x => x.CategoryId)
                            .Intersect(DBCategoryList.Select(d => d.CategoryId)).ToList();

                        if (updateCategoryIDList is not null)
                        {
                            foreach (var oname in updateCategoryIDList)
                            {
                                var category = categoryList.CategoryList.Where(x => x.CategoryId == oname)
                                    .FirstOrDefault();
                                if (category is not null)
                                {
                                    //判断是否有字段修改
                                    var updateCategory = DBCategoryList.Where(x => x.CategoryId == category.CategoryId &&
                                                                                  (x.OriginalName != category.OriginalCategoryName ||
                                                                                  x.CategoryParentId != category.ParentCategoryId ||
                                                                                   x.DisplayName != category.DisplayCategoryName ||                                                                                
                                                                                   x.HasChildren != category.HasChildren)).FirstOrDefault();
                                    if (updateCategory is not null)
                                    {
                                        //新的category元数据
                                        Category newCategory = new Category(category.OriginalCategoryName, 
                                            category.DisplayCategoryName, EnumPlatform.Shopee,category.CategoryId,category.ParentCategoryId);

                                        var dbCategory = DBContext.Category.Where(x => x.OriginalName == category.OriginalCategoryName
                                          && x.DisplayName == category.DisplayCategoryName && x.Platform == EnumPlatform.Shopee && x.CategoryId == category.CategoryId &&
                                          x.CategoryParentId == category.ParentCategoryId).FirstOrDefault();

                                        var c = dbCategory == null ? newCategory : dbCategory;

                                        //旧的rc关系
                                        var relation = DBContext.AreaCategoryRelation.Where(x => x.AId == areaId && x.Platform == EnumPlatform.Shopee
                                        && x.Category.CategoryId == category.CategoryId && x.Status==EnumStatus.ADD).FirstOrDefault();
                                        if (relation is not null)
                                        {
                                            //新建rc关系
                                            AreaCategoryRelation r1 = new AreaCategoryRelation(areaId, c, 
                                                category.CategoryId,
                                               category.ParentCategoryId, EnumStatus.ADD, relation.CId, category.HasChildren, EnumPlatform.Shopee);                                            
                                            DBContext.AreaCategoryRelation.Add(r1);

                                            //更新旧的rc关系
                                            relation.Status = EnumStatus.UPDATE;
                                            relation.NewCategory = c;
                                            DBContext.AreaCategoryRelation.Update(relation);

                                            //更新相关的ra关系
                                            var raList = DBContext.CategoryAttrRelation.Where(c => c.CId == relation.CId).ToList();
                                            if (raList is not null && raList.Count() > 0)
                                            {
                                                foreach (var ra in raList)
                                                {
                                                    ra.category = c;
                                                }
                                                DBContext.CategoryAttrRelation.UpdateRange(raList);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        #endregion
                        DBContext.SaveChanges();
                    }
                    else
                    {
                        return new JsonResult("{'result':-1,'msg':'数据库中没有数据，请执行获取操作！}");
                    }
                    return new JsonResult("{'result':1,'msg':'更新分类目录成功！'}");
                }
                else
                {
                    return new JsonResult("{'result':-1,'msg':'该接口没有返回数据，请重试！}");
                }
            }
            else
            {
                return new JsonResult("{'result':-2,'msg':'" + categoryResult.Message + "'}");
            }
        }
        else
        {
            return new JsonResult("{'result':-1,'msg':'参数传递失败！'}");
        }
    }

   

    /// <summary>
    /// delete RC
    /// </summary>
    /// <param name="CategoryId"></param>
    private void delAreaCategoryRelation(long cid)
    {
        var relation = DBContext.AreaCategoryRelation.Where(x =>x.CId== cid).ToList();
        if (relation is not null)
        {
            foreach(var rc in relation)
            {
                rc.ExcuteTime = DateTime.Now;
                rc.Status = EnumStatus.DELETE;
                DBContext.AreaCategoryRelation.Update(rc);
            }            
        }
    }

    /// <summary>
    /// delete RA
    /// </summary>
    /// <param name="CategoryId"></param>
    private void delCategoryAttrRelation(long cid)
    {
        List<CategoryAttrRelation>? relationRA = DBContext.CategoryAttrRelation.Where(x =>x.CId== cid).ToList();
        if (relationRA is not null)
        {
            foreach (var ra in relationRA)
            {
                ra.ExcuteTime = DateTime.Now;
                ra.Status = EnumStatus.DELETE;
                DBContext.CategoryAttrRelation.Update(ra);
                delAttrValueRelation(ra.AttrId);
            }
        }
    }

    private void delCategoryAttrRelation(long attrId,long Cid)
    {
        var relationRA = DBContext.CategoryAttrRelation.Where(x => x.AttrId == attrId && x.CId == Cid).ToList();
        if (relationRA is not null)
        {
            foreach(var ra in relationRA)
            {
                ra.ExcuteTime = DateTime.Now;
                ra.Status = EnumStatus.DELETE;
                DBContext.CategoryAttrRelation.Update(ra);
                delAttrValueRelation(ra.AttrId);
            }
         }
    }

    /// <summary>
    /// delete RV
    /// </summary>
    /// <param name="attributeId"></param>
    private void delAttrValueRelation(long attrId)
    {
        //根据属性主键id去删除
        var relationRV = DBContext.AttrValueRelation.Where(x => x.AttrId == attrId).ToList();
        foreach (var rv in relationRV)
        {
            rv.ExcuteTime = DateTime.Now;
            rv.Status = EnumStatus.DELETE;
            DBContext.AttrValueRelation.Update(rv);
        }
    }

    /// <summary>
    /// 根据每个分类，去更新attribute，value
    /// </summary>
    /// <param name="shopId"></param>
    /// <param name="categroyID"></param>
    /// <returns></returns>
    [HttpGet]
    [Route("/Shopee/UpdateAttributeValue")]
    public IActionResult UpdateAttributeValue(int categroyID, int shopId,int areaId)
    {
        if (shopId == 0)
        {
            return new JsonResult("{'result':-1,'msg':'shopId参数传递失败！}");
        }
        //根据categoryid和areaID去分块更新
        var categoryModel = DBContext.AreaCategoryRelation.Where(x => x.CategoryId == categroyID
                            && x.AId==areaId && x.Status==EnumStatus.ADD).FirstOrDefault();
        if (categoryModel is not null)
        {           
            RequestGetAttributes requestGetAttributes = new RequestGetAttributes()
            {
                CategoryId = categoryModel.CategoryId,
                ShopId = shopId
            };
            var resultAttr = productMethod.GetAttributes(requestGetAttributes).Result;
            if (!resultAttr.IsSuccess)
            {
                return new JsonResult("{'result':-1,'msg':'查询出错了，[" + resultAttr.Message + "];'}");
            }
            var Iattributes = resultAttr.Result;

            List<CategoryAttrRelation> categoryAttrRelations = new List<CategoryAttrRelation>();           
            if (Iattributes is not null && Iattributes.AttributeList is not null)
            {
                //取出所有要比较的attribute数据
                var DBAttributeList = DBContext.CategoryAttrRelation.Where(x => x.CId== categoryModel.CId
                                      && x.Platform== EnumPlatform.Shopee && x.Status == EnumStatus.ADD).Select(s => new
                {            
                    attrId=s.AttrId,
                    OriginalName = s.attribute.OriginalName,
                    DisplayName = s.attribute.DisplayName,
                    IsMandatory = s.IsMandatory,
                    InputType = s.attribute.InputType,
                    FormatType = s.attribute.FormatType,
                    DateFormatType = s.attribute.DateFormatType,
                    Type = s.attribute.Type,
                    AttributeId=s.attribute.AttributeId,
                    AttributeUnit = s.attribute.AttributeUnit,
                    AttributeValueList = s.attribute.AttributeValuesList,  //根据他更新valueId                                          
                }).ToList();


                if (DBAttributeList is not null && DBAttributeList.Count() > 0)
                {
                    #region  判断有没有新增add attribute;add RA;add value;add RA
                    var addAttriDs = Iattributes.AttributeList.Select(a => a.AttributeId).Except(DBAttributeList.Select(s => s.AttributeId));
                    if (addAttriDs is not null)
                    {
                        foreach (var a in addAttriDs)
                        {
                            var newAttr = Iattributes.AttributeList.Where(x => x.AttributeId == a).FirstOrDefault();
                            if (newAttr is not null)
                            {                               
                                var attribute = DBContext.Attribute.Where(x => x.AttributeId == newAttr.AttributeId
                                                   && x.Platform == EnumPlatform.Shopee).FirstOrDefault();

                                Attribute attrModel = new Attribute(newAttr.OriginalAttributeName, newAttr.DisplayAttributeName,
                                    DBExcute.getInputType(newAttr.InputValidationType),
                                    DBExcute.getFormatType(newAttr.FormatType), DBExcute.getDateFormatType(newAttr.DateFormatType),
                                    DBExcute.getType(newAttr.InputType), DBExcute.getStringByArray(newAttr.AttributeUnit),
                                    DBExcute.getStringByArray(newAttr.AttributeValueList), null, null, EnumPlatform.Shopee, null, null, null,newAttr.AttributeId);

                                var model = attribute == null ? attrModel : attribute;
                                var categoryAttrRelation = new CategoryAttrRelation(categoryModel.CId, model, newAttr.AttributeId, EnumPlatform.Shopee,
                                                                                    DBExcute.getIsMandatory(newAttr.IsMandatory), 0, null, null, null);
                                DBContext.CategoryAttrRelation.Add(categoryAttrRelation);
                                if (newAttr.AttributeValueList.Count() > 0)
                                {                                    
                                    List<AttrValueRelation> attrValueRelations = new List<AttrValueRelation>();
                                    foreach (var v in newAttr.AttributeValueList)
                                    {
                                        var valueModel = new Value(v.OriginalValueName, v.DisplayValueName, EnumPlatform.Shopee, v.ValueId);
                                        var temp = DBContext.Value.Where(x => x.OriginalName == v.OriginalValueName && x.Platform == EnumPlatform.Shopee).FirstOrDefault();
                                        var valueRelation = new AttrValueRelation(model, temp is null ? valueModel : temp, v.ValueId, EnumPlatform.Shopee, categoryModel.CId);
                                        attrValueRelations.Add(valueRelation);
                                    }
                                    DBContext.AttrValueRelation.AddRange(attrValueRelations);
                                }
                            }
                            else
                            {
                                return new JsonResult("{'result':-1,'msg':'[" + a.ToString() + "]属性ID不在接口数据中，请确认！}");
                            }
                        }                       
                    }
                    #endregion

                    #region 判断有没有删除 del ra;del rv;
                    var deleteAttriDs = DBAttributeList.Select(a => a.AttributeId).Except(Iattributes.AttributeList.Select(s => s.AttributeId));
                    if (deleteAttriDs is not null)
                    {
                        foreach (var d in deleteAttriDs)
                        {
                            var deleteAttrId = DBAttributeList.Where(x => x.AttributeId == d).FirstOrDefault();
                            if (deleteAttrId is not null)
                            {
                                delCategoryAttrRelation(deleteAttrId.attrId, categoryModel.CId);
                            }
                            else
                            {
                                //新增的id不存在
                                return new JsonResult("{'result':-1,'msg':'[" + d.ToString() + "]目录不在接口数据中，请确认！}");
                            }
                        }
                    }
                    #endregion

                    #region 判断有没有修改 add attribute;add newRA;update RA;update RV
                    List<Attribute> LstAttributes = new List<Attribute>();
                    var updateAttrIDs = Iattributes.AttributeList.Select(a => a.AttributeId).Intersect(DBAttributeList.Select(s => s.AttributeId));
                    if (updateAttrIDs is not null)   //attributeId 交集 
                    {
                        foreach (var oname in updateAttrIDs)
                        {
                            var model = Iattributes.AttributeList.Where(x => x.AttributeId == oname).FirstOrDefault();
                            if(model is not null)
                            {
                                var attrData = DBAttributeList.Where(x => x.AttributeId == model.AttributeId).FirstOrDefault();
                                var updateModel = DBAttributeList.Where(x => x.AttributeId == model.AttributeId &&
                                          (x.OriginalName != model.OriginalAttributeName ||
                                          x.DisplayName != model.DisplayAttributeName ||
                                           x.IsMandatory != DBExcute.getIsMandatory(model.IsMandatory) ||
                                           x.InputType != DBExcute.getInputType(model.InputValidationType) ||
                                           x.FormatType != DBExcute.getFormatType(model.FormatType) ||
                                           x.DateFormatType != DBExcute.getDateFormatType(model.DateFormatType) ||
                                           x.Type != DBExcute.getType(model.InputType) ||
                                           x.AttributeUnit !=DBExcute.getStringByArray(model.AttributeUnit))).FirstOrDefault();
                                if (updateModel is not null)  //有修改
                                {                                 
                                     Attribute attrModel = new Attribute(model.OriginalAttributeName,
                                      model.DisplayAttributeName, DBExcute.getInputType(model.InputValidationType),
           DBExcute.getFormatType(model.FormatType), DBExcute.getDateFormatType(model.DateFormatType),
            DBExcute.getType(model.InputType), DBExcute.getStringByArray(model.AttributeUnit),
           DBExcute.getStringByArray(model.AttributeValueList), null, null, EnumPlatform.Shopee, null, null, null, model.AttributeId);

                                 var dbAttr=DBContext.Attribute.Where(x => x.AttributeId == model.AttributeId && x.OriginalName == model.OriginalAttributeName
                                    && x.DisplayName == model.DisplayAttributeName && x.InputType == DBExcute.getInputType(model.InputValidationType)
                                    && x.FormatType == DBExcute.getFormatType(model.FormatType) && x.DateFormatType == DBExcute.getDateFormatType(model.DateFormatType)
                                    && x.Type == DBExcute.getType(model.InputType) && x.AttributeUnit == DBExcute.getStringByArray(model.AttributeUnit)).FirstOrDefault();

                                    var a = dbAttr == null ? attrModel : dbAttr;
                                    #region
                                    var oldRa = DBContext.CategoryAttrRelation.Where(x => x.CId == categoryModel.Id && x.attribute.AttributeId == model.AttributeId && x.Status==EnumStatus.ADD).FirstOrDefault();
                                    if (oldRa is not null)
                                    {
                                        var categoryAttrRelation = new CategoryAttrRelation(categoryModel.CId, a, model.AttributeId,
                                           EnumPlatform.Shopee, DBExcute.getIsMandatory(model.IsMandatory), oldRa.AttrId,null,null,null);                                        
                                        oldRa.Status = EnumStatus.UPDATE;                                        
                                        oldRa.NewAttribute = a;
                                        DBContext.CategoryAttrRelation.Update(oldRa);
                                        categoryAttrRelations.Add(categoryAttrRelation);
                                        var rvList = DBContext.AttrValueRelation.Where(x => x.AttrId == oldRa.AttrId).ToList();
                                        if (rvList is not null)
                                        {
                                            foreach (var rv in rvList)
                                            {
                                                rv.Attribute = a;
                                            }
                                            DBContext.AttrValueRelation.UpdateRange(rvList);
                                        }
                                        UpdateValue(categoryModel.CId, model, oldRa.AttrId);
                                    }
                                    #endregion
                                }
                                else
                                {
                                    UpdateValue(categoryModel.CId, model, attrData.attrId);
                                }                               
                            }
                        }                                                    
                    }
                    #endregion
                    categoryModel.ChangeFlag = true;
                    DBContext.AreaCategoryRelation.Update(categoryModel);
                    DBContext.CategoryAttrRelation.AddRange(categoryAttrRelations);
                    DBContext.SaveChanges();
                }
                return new JsonResult("{'result':1,'msg':'categroyID:" + categoryModel.CategoryId + "下属性值保存成功！'}");
            }
            else
            {
                DBContext.SaveChanges();
                return new JsonResult("{'result':1,'msg':'没有找到该分类下的属性！categoryId:[" + categoryModel.CategoryId + "];'}");
            }
        }
        else
        {
            return new JsonResult("{'result':-1,'msg':'没有找到该分类目录ID！categoryId:[" + categroyID + "];'}");
        }
    }

     void UpdateValue(long cid,ResponseGetAttributes.Attribute model, long attrId)
    {
        //获取指定attrId下的value值
        var DBValueLists = DBContext.AttrValueRelation.Where(x => x.AttrId == attrId && x.Platform == EnumPlatform.Shopee
         && x.Status == EnumStatus.ADD &&x.CId==cid ).Select(s => new
         {
             AttrId = s.AttrId,
             VId = s.VId,
             ValueId = s.Value.ValueId,
             OriginalName = s.Value.OriginalName,
             DisplayName = s.Value.DisplayName,
         }).ToList();

        var valueList = model.AttributeValueList;

        #region 判断value有没有新增 add value;add RV
        var addValue = valueList.Select(x =>x.ValueId).Except(DBValueLists.Select(x => x.ValueId)).ToList();
        if (addValue is not null && addValue.Count() > 0)
        {
            foreach (var a in addValue)
            {              
                var newValue = valueList.Where(x => x.ValueId == a).FirstOrDefault();
                if (newValue is not null)
                {
                    var valueModel = new Value(newValue.OriginalValueName, newValue.DisplayValueName, EnumPlatform.Shopee,newValue.ValueId);
                    var temp = DBContext.Value.Where(x => x.OriginalName == newValue.OriginalValueName && x.DisplayName == newValue.DisplayValueName
                      && x.Platform == EnumPlatform.Shopee && x.ValueId == newValue.ValueId).FirstOrDefault();

                    var valueRelation = new AttrValueRelation(attrId, temp==null?valueModel: temp, newValue.ValueId, EnumPlatform.Shopee,0,cid);                   
                    DBContext.AttrValueRelation.Add(valueRelation);
                }
            }
        }
        #endregion

        #region 判断value有没有删除 update RV=del
        var deleteValue = DBValueLists.Select(x => x.ValueId).Except(valueList.Select(x => x.ValueId)).ToList();
        if (deleteValue is not null && deleteValue.Count() > 0)
        {
            foreach (var d in deleteValue)
            {               
                var delValue = DBContext.AttrValueRelation.Where(x => x.Value.ValueId == d).ToList();
                if (delValue is not null)
                {
                    foreach(var rv in delValue)
                    {
                        rv.Status = EnumStatus.DELETE;
                        rv.ExcuteTime = DateTime.Now;
                        DBContext.AttrValueRelation.Update(rv);
                    }                    
                }
            }
        }
        #endregion

        #region 判断value有没有修改 add value;add newRV;update RV
        List<AttrValueRelation> valueRelationList = new List<AttrValueRelation>();
        List<Value> ValueList = new List<Value>();

        var updateValue = DBValueLists.Select(x => x.ValueId).Intersect(valueList.Select(x => x.ValueId)).ToList();
        if (updateValue is not null && updateValue.Count() > 0)
        {
            foreach (var v in updateValue)
            {               
                var value = valueList.Where(x => x.ValueId == v).FirstOrDefault();
                var ValueModel = DBValueLists.Where(x => x.ValueId == value.ValueId &&( x.OriginalName != value.OriginalValueName ||
                         x.DisplayName != value.DisplayValueName)).FirstOrDefault();
                if (ValueModel is not null)
                {
                    var valueModel = new Value(value.OriginalValueName, value.DisplayValueName, EnumPlatform.Shopee,value.ValueId);

                    var temp = DBContext.Value.Where(x => x.OriginalName == value.OriginalValueName && x.DisplayName == value.DisplayValueName
                    && x.Platform == EnumPlatform.Shopee && x.ValueId == value.ValueId).FirstOrDefault();

                    var valueTemp = temp == null ? valueModel : temp;

                    var oldValue = DBContext.AttrValueRelation.Where(x => x.AttrId == attrId 
                               && x.Value.ValueId == value.ValueId && x.CId==cid).FirstOrDefault();
                    if (oldValue is not null)
                    {
                        var valueRelation = new AttrValueRelation(attrId, valueTemp, value.ValueId, EnumPlatform.Shopee,
                           oldValue.VId, cid);                        
                        valueRelationList.Add(valueRelation);
                        oldValue.Status = EnumStatus.UPDATE;                  
                        oldValue.NewValue = valueTemp;
                        DBContext.AttrValueRelation.Update(oldValue);
                    }
                }
            }
        }         
        DBContext.AttrValueRelation.AddRange(valueRelationList);
        #endregion
    }
}
